package gapidt.plugin.wizards;

import gapidt.common.Locale;
import gapidt.nlp.SemanticUtils;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;

/**
 * The "New" wizard page allows setting the container for the new file as well
 * as the file name. The page will only accept file name without the extension
 * OR with the extension that matches the expected one (mpe).
 */

public class WsdlGeneratorPage1 extends WizardPage {
	
	private TypesSelectorTree typesSelectorTree;
	private Combo wsdlGeneratorDropDown;
	private String[] wsdlGenerationMethods = {"Gapidt WSDL generator", "Axis2 Java2WSDL generator", "OW2 EasyWSDL generator"};
	private Text wsdlFileText;
	private Text wsdlFileContainerText;
	private Text wsdlTargetNamespaceText;
	
	private IType[] types;
	private IJavaProject javaProject;

	/**
	 * Constructor for SampleNewWizardPage.
	 * 
	 * @param pageName
	 */
	public WsdlGeneratorPage1(IType[] types, IJavaProject javaProject) {
		super("wsdlGeneratorPage1");
		setTitle(Locale.getMessage("gapidt.plugin.wizards.WsdlGeneratorWizard.title"));
		setDescription(Locale.getMessage("gapidt.plugin.wizards.WsdlGeneratorWizard.description"));
		this.types = types;
		this.javaProject = javaProject;
	}

	/**
	 * @see IDialogPage#createControl(Composite)
	 */
	public void createControl(Composite parent) {
		Composite container = new Composite(parent, SWT.NULL);
		
		//Create layout
		GridLayout layout = new GridLayout();
		container.setLayout(layout);
		
		layout.numColumns = 1;
		layout.verticalSpacing = 9;

		// WSDL generation method
		Label label = new Label(container, SWT.NULL);
		label.setText("&"+Locale.getMessage("wsdl_generator")+":");
		
		wsdlGeneratorDropDown = new Combo(container, SWT.DROP_DOWN | SWT.BORDER);
		wsdlGeneratorDropDown.setItems(wsdlGenerationMethods);
		wsdlGeneratorDropDown.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				WsdlGeneratorPage2 page2 = (WsdlGeneratorPage2) getWizard().getPage("wsdlGeneratorPage2");
				if(page2 != null){
					if(getWsdlGenerationMethod() != WsdlGeneratorWizard.WSDL_GENERATOR_GAPIDT)
						page2.setSeparatedSchemaEnabled(false);
					else
						page2.setSeparatedSchemaEnabled(true);
					if(getWsdlGenerationMethod() == WsdlGeneratorWizard.WSDL_GENERATOR_OW2){
						wsdlTargetNamespaceText.setEnabled(false);
						page2.setTargetNamespaceEnabled(false);
					}else{
						wsdlTargetNamespaceText.setEnabled(true);
						page2.setTargetNamespaceEnabled(true);
					}
						
				}
				dialogChanged();
			}
		});
		
		Label horizontalLine = new Label(container, SWT.SEPARATOR | SWT.SHADOW_OUT | SWT.HORIZONTAL);
		horizontalLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
		//Java type field
		label = new Label(container, SWT.NULL);
		label.setText("&"+Locale.getMessage("java_classes")+":");

		
		Composite treeContainer = new Composite(container, SWT.NULL);
		treeContainer.setSize(SWT.DEFAULT, 200);
		
		typesSelectorTree = new TypesSelectorTree(treeContainer, javaProject, 600, 200);
		typesSelectorTree.getTree().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		typesSelectorTree.addSelectionListener(new Listener() {
	        public void handleEvent(Event event) {
	            if (event.detail == SWT.CHECK) {
	                dialogChanged();
	            }
	        }
	    });
		
		//WSDL file name
		label = new Label(container, SWT.NULL);
		label.setText("&"+Locale.getMessage("wsdl_document")+":");

		Composite wsdlContainer = new Composite(container, SWT.NULL);
		GridLayout wsdlLayout = new GridLayout();
		wsdlContainer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		wsdlContainer.setLayout(wsdlLayout);
		wsdlLayout.numColumns = 3;
		wsdlLayout.verticalSpacing = 2;
		wsdlLayout.horizontalSpacing = 5;
		
		label = new Label(wsdlContainer, SWT.NULL);
		label.setText("&"+Locale.getMessage("file_name")+":");
		
		wsdlFileText = new Text(wsdlContainer, SWT.BORDER | SWT.SINGLE);
		wsdlFileText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		wsdlFileText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		(new Label(wsdlContainer, SWT.NULL)).setText("");
		
		label = new Label(wsdlContainer, SWT.NULL);
		label.setText("&"+Locale.getMessage("container")+":");
		
		wsdlFileContainerText = new Text(wsdlContainer, SWT.BORDER | SWT.SINGLE);
		wsdlFileContainerText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		wsdlFileContainerText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		Button button = new Button(wsdlContainer, SWT.PUSH);
		button.setText(Locale.getMessage("browse")+"...");
		button.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleContainerBrowse(wsdlFileContainerText, Locale.getMessage("select_container"));
			}
		});
		
		//WSDL target namespace
		label = new Label(wsdlContainer, SWT.NULL);
		label.setText("&"+Locale.getMessage("target_ns")+":");

		wsdlTargetNamespaceText = new Text(wsdlContainer, SWT.BORDER | SWT.SINGLE);
		wsdlTargetNamespaceText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		wsdlTargetNamespaceText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				dialogChanged();
			}
		});
		
		(new Label(wsdlContainer, SWT.NULL)).setText("");
		
		initialize();
		dialogChanged();
		setControl(container);
	}

	/**
	 * Tests if the current workbench selection is a suitable container to use.
	 */
	private void initialize() {
		if (types != null && types.length > 0) {
			
			wsdlGeneratorDropDown.select(WsdlGeneratorWizard.WSDL_GENERATOR_GAPIDT);
			
			IContainer container = types[0].getCompilationUnit().getResource().getParent();
			wsdlFileContainerText.setText(container.getFullPath().toString());
			typesSelectorTree.setSelectedTypes(types);
			
			wsdlFileText.setText("services.wsdl");
			wsdlTargetNamespaceText.setText("http://example.com/services/definitions");
			
			wsdlFileText.forceFocus();
		}else{
			wsdlFileText.setText("services.wsdl");
		}
	}

	/**
	 * Uses the standard container selection dialog to choose the new value for
	 * the container field.
	 */
	private void handleContainerBrowse(Text textElement, String dialogTitle){
		ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin.getWorkspace().getRoot(), false, dialogTitle);
		
		if (dialog.open() == ContainerSelectionDialog.OK) {
			Object[] result = dialog.getResult();
			if (result.length == 1)
				textElement.setText(((Path) result[0]).toString());
		}
	}
	
	/**
	 * Ensures that both text fields are set.
	 */

	private void dialogChanged() {
		IResource container = ResourcesPlugin.getWorkspace().getRoot()
				.findMember(new Path(getWsdlFileContainerName()));
		
		if (getSelectedTypes().length == 0){
			updateStatus(Locale.getMessage("java_classes_empty"));
			return;
		}
		
		if (getWsdlGenerationMethod() < 0) {
			updateStatus(Locale.getMessage("wsdl_generator_invalid"));
			return;
		}
		
		IType[] selectedTypes = getSelectedTypes();
		if (selectedTypes == null || selectedTypes.length == 0) {
			updateStatus(Locale.getMessage("java_classes_empty"));
			return;
		}
		
		if(getWsdlGenerationMethod() == WsdlGeneratorWizard.WSDL_GENERATOR_AXIS2 && selectedTypes.length > 1){
			updateStatus(Locale.getMessage("java_classes_too_many"));
			return;
		}
		
		if (getWsdlFileContainerName().length() == 0) {
			updateStatus(Locale.getMessage("container_empty"));
			return;
		}
		if (container == null || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) {
			updateStatus(Locale.getMessage("container_not_found"));
			return;
		}
		if (!container.isAccessible()) {
			updateStatus(Locale.getMessage("container_not_writable"));
			return;
		}
		
		if(!validFileName(wsdlFileText, "wsdl", "wsdl_file"))
			return;
		
		if(!validTargetNamespace(wsdlTargetNamespaceText, "wsdl_target_ns"))
			return;

		updateStatus(null);
	}

	private void updateStatus(String message) {
		setErrorMessage(message);
		setPageComplete(message == null);
	}

	public int getWsdlGenerationMethod() {
		if(wsdlGeneratorDropDown != null)
			return wsdlGeneratorDropDown.getSelectionIndex();
		return -1;
	}
	
	public IType[] getSelectedTypes() {
		if(typesSelectorTree != null)
			return typesSelectorTree.getSelectedTypes();
		return null;
	}
	
	public String getWsdlFileContainerName() {
		if(wsdlFileContainerText != null)
			return wsdlFileContainerText.getText();
		return "";
	}

	public String getWsdlFileName() {
		if(wsdlFileText != null)
			return wsdlFileText.getText();
		return "";
	}
	
	public String getWsdlTargetNamespace() {
		if(wsdlTargetNamespaceText != null)
			return wsdlTargetNamespaceText.getText();
		return "";
	}
	
	public boolean validFileName(Text textInput, String extension, String inputKey){
		String value = textInput.getText();
		if (value.length() == 0) {
			updateStatus(Locale.getMessage(inputKey+"_empty"));
			return false;
		}
		if (value.replace('\\', '/').indexOf('/', 1) > 0) {
			updateStatus(Locale.getMessage(inputKey+"_invalid"));
			return false;
		}
		int dotLoc = value.lastIndexOf('.');
		String ext = value.substring(dotLoc + 1);
		if (dotLoc == -1) ext = "";
		if (ext.equalsIgnoreCase(extension) == false) {
			updateStatus(Locale.getMessage(inputKey+"_wrong_extension"));
			return false;
		}
		return true;
	}
	
	public boolean validTargetNamespace(Text textInput, String inputKey){
		String value = textInput.getText();
		if (value.length() == 0) {
			updateStatus(Locale.getMessage(inputKey+"_empty"));
			return false;
		}
		return true;
	}
	
	public boolean validUrl(Text textInput, String inputKey){
		String value = textInput.getText();
		if (value.length() == 0) {
			updateStatus(Locale.getMessage(inputKey+"_empty"));
			return false;
		}
		return true;
	}
}